﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Web;

namespace Codemonk.Pease.Server.AspectMonitors
{
    public class CachedLogAspectMonitor : IAspectMonitor<HttpContext>
    {
        public static EventLog EventLog = new EventLog { Source = "Codemonk.Pease" };
        private static void TraceInformation(string methodName, HttpContext context, object instance, string message)
        {
            try
            {
                var path = string.Concat(System.IO.Path.GetDirectoryName(typeof(CachedLogAspectMonitor).Assembly.CodeBase.Replace("file:///", "")), "\\codemonk.pease.server.log");
                System.IO.File.AppendAllText(
                   path,
                    string.Format("{0},{1},{2},{3}.{4},{5}\r\n",
                    DateTime.Now.ToString("yyyyMMdd-hh24mmss-ffff"),
                    System.Threading.Thread.CurrentThread.ManagedThreadId,
                    context.Request.UserHostAddress,
                    instance.GetType().Name,
                    methodName,
                    message));
            }
            catch { }
        }

        private static IDictionary<int, IDictionary<int, IDictionary<int, object>>> cache = new ConcurrentDictionary<int, IDictionary<int, IDictionary<int, object>>>();

        public void BeforeInvoke(string methodName, HttpContext context, object instance, object entity, Type backType, Action<object> replacer)
        {
            TraceInformation(methodName, context, instance, "开始执行");
            if (entity == null) return;
            var interfaceHash = instance.GetType().GetHashCode();
            IDictionary<int, IDictionary<int, object>> idict;
            if (cache.TryGetValue(interfaceHash, out idict))
            {
                if (idict != null)
                {
                    var methodHash = methodName.GetHashCode();
                    IDictionary<int, object> mdict;
                    if (idict.TryGetValue(methodHash, out mdict))
                    {
                        if (mdict != null)
                        {
                            var entityHash = entity.GetHashCode();
                            object value;
                            if (mdict.TryGetValue(entityHash, out value)) replacer(value);
                        }
                    }
                }
            }
        }

        public void AfterInvoke(string methodName, HttpContext context, object instance, object entity, object backvalue, Type backType, Action<object> replacer)
        {
            TraceInformation(methodName, context, instance, "执行完成");
            if (entity == null) return;
            var interfaceHash = instance.GetType().GetHashCode();
            IDictionary<int, IDictionary<int, object>> idict;
            if (!cache.TryGetValue(interfaceHash, out idict)) cache[interfaceHash] = (idict = new ConcurrentDictionary<int, IDictionary<int, object>>());
            if (idict == null) cache[interfaceHash] = new ConcurrentDictionary<int, IDictionary<int, object>>();
            var methodHash = methodName.GetHashCode();
            IDictionary<int, object> mdict;
            if (!idict.TryGetValue(methodHash, out mdict)) idict[methodHash] = (mdict = new ConcurrentDictionary<int, object>());
            var entityHash = entity.GetHashCode();
            mdict[entityHash] = backvalue;
        }

        public void CatchException(string methodName, HttpContext context, object instance, object entity, Type backType, Exception exception, Action<object> replacer)
        {
            TraceInformation(methodName, context, instance, string.Format("执行出错,{0}", exception.Message));
        }
    }
}
